package com.ruoyi.system.listener;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.TypeReference;
import com.aliyuncs.exceptions.ClientException;
import com.ruoyi.common.constant.WorkFlowConstants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.WorkFlowException;
import com.ruoyi.common.utils.aliyun.SendMessage;
import com.ruoyi.system.Constants.CommonConstants;
import com.ruoyi.system.domain.MsgConfiguration;
import com.ruoyi.system.domain.MsgLog;
import com.ruoyi.system.domain.ProcessTemplates;
import com.ruoyi.system.domain.dto.json.ChildNode;
import com.ruoyi.system.domain.dto.json.Properties;
import com.ruoyi.system.domain.dto.json.UserInfo;
import com.ruoyi.system.domain.enums.AssigneeTypeEnums;
import com.ruoyi.system.service.*;
import com.ruoyi.system.utils.BpmnModelUtils;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.UserTask;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.ExecutionListener;
import org.flowable.variable.api.persistence.entity.VariableInstance;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;



/**
 * 执行监听器
 * start：在流程实例启动时触发。
 * end：在流程实例结束时触发。
 * take:流程连线被执行时触发。
 * 设置审批人   start触发
 * @desc 本项目精髓代码实现-> 所有属性都在内存中取得,且该类最重要的一点就是  下面有一个if判断,防止人员重复解析--->
 */
@Component
@Slf4j
public class CounterSignListener implements ExecutionListener {
    @Resource
    private RepositoryService repositoryService;
    @Resource
    private ISysDeptService departmentsService;
    @Resource
    private ISysUserService userService;
    @Resource
    private IProcessTemplatesService processTemplatesService;
    @Resource
    private IMsgConfigurationService msgConfigurationService;
    @Resource
    private IMsgLogService msgLogService;

    @Override
    public void notify(DelegateExecution execution) {
        //获取当前标签的id
        String currentActivityId = execution.getCurrentActivityId();
        Process mainProcess = repositoryService.getBpmnModel(execution.getProcessDefinitionId()).getMainProcess();
        UserTask userTask = (UserTask) mainProcess.getFlowElement(currentActivityId);
        log.info("UserTask信息:{}"+userTask);
        //获取节点信息
        ChildNode childNode = getNode(execution);
        //获取当前节点审批人信息
        List<String> assigneeList= new ArrayList<>();
        String variable=currentActivityId+WorkFlowConstants.ASSIGNEE_LIST_SUFFIX;
        List usersValue = (List) execution.getVariable(variable);
        if(usersValue==null){
            ChildNode currentNode = BpmnModelUtils.getChildNode(childNode, currentActivityId);
            if(currentNode==null){
                throw new WorkFlowException("查找审批人失败,请联系管理员重试");
            }
            Properties props = currentNode.getProps();
            String assignedType = props.getAssignedType();
            Map<String, Object> nobody = props.getNobody();
            //指定人员
            if(AssigneeTypeEnums.ASSIGN_USER.getTypeName().equals(assignedType)){
                List<UserInfo> assignedUser = props.getAssignedUser();
                for (UserInfo userInfo : assignedUser) {
                    assigneeList.add(userInfo.getId());
                }
            }
            //发起人自己
            else if(AssigneeTypeEnums.SELF_SELECT.getTypeName().equals(assignedType)){
                List<String> assigneeUsers = (List<String>) execution.getVariable(currentActivityId);
                if(assigneeUsers!=null){
                    assigneeList.addAll(assigneeUsers);
                }
            }
            //角色
            else if(AssigneeTypeEnums.ROLE.getTypeName().equals(assignedType)){
                throw new WorkFlowException("前端现在角色选择器有问题,等待联调");
//                LambdaQueryWrapper<Users> lambdaQueryWrapper=new LambdaQueryWrapper<>();
//                lambdaQueryWrapper.in(Users::getDepartmentIds,roleIds);
//                UserService userService = SpringContextHolder.getBean(UserService.class);
//                List<Users> list = userService.list(lambdaQueryWrapper);
//                for (Users users : list) {
//                    flwHisTaskActors.add(FlwTaskActor.ofUser(users.getUserId()+"",users.getUserName()));
//                }
            }
            //发起人自己
            else if(AssigneeTypeEnums.SELF.getTypeName().equals(assignedType)){
                String startUserJson = execution.getVariable(CommonConstants.START_USER_INFO, String.class);
                UserInfo userInfo = JSONObject.parseObject(startUserJson, new TypeReference<UserInfo>() {
                });
                assigneeList.add(userInfo.getId());
            }
            //发送消息
            String templateId = (String)execution.getVariableInstance("templateId").getValue();
            ProcessTemplates processTemplates = processTemplatesService.selectProcessTemplatesByTemplateId(templateId);
            Long startMsg = processTemplates.getStartMsg();
            for(String userId : assigneeList){
                msgLogService.sendMsg(startMsg,userId);
            }
            //如果审批人为空的情况
            if(CollUtil.isEmpty(assigneeList)){
                String handler = MapUtil.getStr(nobody,WorkFlowConstants.ASSIGNEE_NULL_ACTION_NAME);
                //自动通过
                if(WorkFlowConstants.TO_PASS_ACTION.equals(handler)){
                    assigneeList.add(WorkFlowConstants.DEFAULT_NULL_ASSIGNEE);
                    execution.setVariable(variable,assigneeList);
                }
                //自动驳回
                else if(WorkFlowConstants.TO_REFUSE_ACTION.equals(handler)){
                    execution.setVariable(WorkFlowConstants.AUTO_REFUSE_STR,Boolean.TRUE);
                    assigneeList.add(WorkFlowConstants.DEFAULT_NULL_ASSIGNEE);
                    execution.setVariable(variable,assigneeList);
                } else{
                    throw new WorkFlowException("找不到审批人,请检查配置!!!");
                }
            }
            else{
                execution.setVariable(variable,assigneeList);
            }

        }

    }

    //发送短信提醒
    public void sendTextMsg(String userId, String phonenumber,MsgConfiguration msgConfiguration){
        Integer msgCon = 1111;
        try {
            MsgLog msgLog = new MsgLog();
            msgLog.setMsgContent(msgConfiguration.getMsgContent());
            msgLog.setMsgTitile(msgConfiguration.getMsgTitile());
            msgLog.setReceiver(userId);
            //站内消息
            msgLog.setSendType("1");
            //消息发送失败
            if (!SendMessage.sendSms(phonenumber, msgCon)) {
                msgLog.setStatus("1");
                msgLogService.insertMsgLog(msgLog);
            }
            msgLogService.insertMsgLog(msgLog);
        } catch (ClientException e) {
            e.printStackTrace();
        }
    }


    private ChildNode getNode(DelegateExecution execution) {

        Process mainProcess = repositoryService.getBpmnModel(execution.getProcessDefinitionId()).getMainProcess();
        String dingDing = mainProcess.getAttributeValue(WorkFlowConstants.FLOWABLE_NAME_SPACE, WorkFlowConstants.FLOWABLE_NAME_SPACE_NAME);
        JSONObject jsonObject = JSONObject.parseObject(dingDing, new TypeReference<JSONObject>() {
        });
        String processJson = jsonObject.getString(WorkFlowConstants.VIEW_PROCESS_JSON_NAME);
        ChildNode childNode = JSONObject.parseObject(processJson, new TypeReference<ChildNode>(){});
        return childNode;
    }
}
